/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package com.inspur.edp.lcm.metadata.core;

import com.inspur.edp.lcm.metadata.api.IMdExtRuleContent;
import com.inspur.edp.lcm.metadata.api.entity.GspMetadata;
import com.inspur.edp.lcm.metadata.api.entity.GspProject;
import com.inspur.edp.lcm.metadata.api.entity.Metadata4Ref;
import com.inspur.edp.lcm.metadata.api.entity.Metadata4RefDto;
import com.inspur.edp.lcm.metadata.api.entity.MetadataDto;
import com.inspur.edp.lcm.metadata.api.entity.MetadataFilter;
import com.inspur.edp.lcm.metadata.api.entity.MetadataHeader;
import com.inspur.edp.lcm.metadata.api.entity.MetadataIndexItemDto;
import com.inspur.edp.lcm.metadata.api.entity.MetadataPackage;
import com.inspur.edp.lcm.metadata.api.entity.MetadataProject;
import com.inspur.edp.lcm.metadata.api.entity.MetadataType;
import com.inspur.edp.lcm.metadata.api.service.GspProjectService;
import com.inspur.edp.lcm.metadata.api.service.MetadataService;
import com.inspur.edp.lcm.metadata.common.FileServiceImp;
import com.inspur.edp.lcm.metadata.common.Utils;
import com.inspur.edp.lcm.metadata.devcommon.ManagerUtils;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.List;
import java.util.Objects;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author zhaoleitr
 */
public class MetadataServiceImp implements MetadataService {
    private static final Logger log = LoggerFactory.getLogger(MetadataServiceImp.class);

    private final GspProjectService gspProjectService = new GspProjectServiceImp();
    private final MetadataProjectCoreService metadataProjectService = new MetadataProjectCoreService();
    private final MetadataCoreManager metadataCoreManager = new MetadataCoreManager();

    @Override
    public GspMetadata initializeMetadataEntity(GspMetadata metadata) {
        metadataCoreManager.initializeMetadataEntity(metadata);
        return metadata;
    }

    @Override
    public void createMetadata(String path, GspMetadata metadata) {
        String absolutePath = ManagerUtils.getAbsolutePath(path);
        metadataCoreManager.createMetadata(absolutePath, metadata);
    }

    @Override
    public GspMetadata loadMetadata(String metadataFileName, String path) {
        Utils.checkEmpty(metadataFileName, "parameter value is empty,paramter is metadataFileName");
        Utils.checkEmpty(path, "parameter value is empty,paramter is path");
        String absolutePath = ManagerUtils.getAbsolutePath(path);
        GspMetadata metadata;
        try {
            metadata = metadataCoreManager.loadMetadata(metadataFileName, absolutePath);
        } catch (Exception e) {
            String ralativePath = ManagerUtils.getRalativePath(absolutePath) + "/" + metadataFileName;
            throw new RuntimeException(String.format("找不到元数据，元数据路径为：%s", ralativePath));
        }
        metadata.setRelativePath(ManagerUtils.getRalativePath(metadata.getRelativePath()));
        return metadata;
    }

    @Override
    public GspMetadata loadMetadata(String metadataPath) {
        Utils.checkEmpty(metadataPath, "parameter value is empty,paramter is metadataPath");
        String absolutePath = ManagerUtils.getAbsolutePath(metadataPath);
        GspMetadata metadata;
        try {
            metadata = metadataCoreManager.loadMetadata(absolutePath);
        } catch (Exception e) {
            String ralativePath = ManagerUtils.getRalativePath(absolutePath);
            throw new RuntimeException(String.format("找不到元数据，元数据路径为：%s", ralativePath));
        }
        metadata.setRelativePath(ManagerUtils.getRalativePath(metadata.getRelativePath()));
        return metadata;
    }

    @Override
    public GspMetadata loadMetadataByMetadataId(String metadataId, String path) {
        Utils.checkEmpty(metadataId, "parameter value is empty,paramter is metadataFileName");
        Utils.checkEmpty(path, "parameter value is empty,paramter is path");
        String absolutePath = ManagerUtils.getAbsolutePath(path);
        return metadataCoreManager.loadMetadataByMetadataId(metadataId, absolutePath);
    }

    @Override
    public GspMetadata loadMetadataInBo(String metadataFullPath, String currentProjPath) {
        String absoluteMetadataPath = ManagerUtils.getAbsolutePath(metadataFullPath);
        String absoluteProjPath = ManagerUtils.getAbsolutePath(currentProjPath);
        GspMetadata metadata = metadataCoreManager.loadMetadataInBo(absoluteMetadataPath, absoluteProjPath);
        metadata.setRelativePath(ManagerUtils.getRalativePath(metadata.getRelativePath()));
        return metadata;
    }

    @Override
    public GspMetadata getRefMetadata(String spacePath, String metadataID) {
        if (!spacePath.isEmpty()) {
            spacePath = ManagerUtils.getAbsolutePath(spacePath);
        }
        return metadataCoreManager.getRefMetadata(metadataID, spacePath);
    }

    @Override
    public GspMetadata getMetadataWithoutContent(String fullPath) {
        String absolutePath = ManagerUtils.getAbsolutePath(fullPath);
        GspMetadata metadata = metadataCoreManager.getMetadataWithoutContent(absolutePath);
        metadata.setRelativePath(ManagerUtils.getRalativePath(metadata.getRelativePath()));
        return metadata;
    }

    @Override
    public void deleteMetadata(String path, String metadataFileName) {
        String absolutePath = ManagerUtils.getAbsolutePath(path);
        metadataCoreManager.deleteMetadata(absolutePath, metadataFileName);
    }

    @Override
    public void deleteFolder(String path) {
        String absolutePath = ManagerUtils.getAbsolutePath(path);
        metadataCoreManager.deleteFolder(absolutePath);
    }

    @Override
    public void renameMetadata(String oldFileName, String newFileName, String metadataFilePath) {
        String absolutePath = ManagerUtils.getAbsolutePath(metadataFilePath);
        metadataCoreManager.renameMetadata(oldFileName, newFileName, absolutePath);
    }

    @Override
    public List<GspMetadata> getMetadataList(String spacePath, List<String> metadataTypes) {
        String absolutePath = ManagerUtils.getAbsolutePath(spacePath);
        List<GspMetadata> result = metadataCoreManager.getMetadataList(absolutePath, metadataTypes);
        return result;
    }

    @Override
    public List<MetadataDto> getMetadataListInBo(String path, List<String> metadataTypes) {
        String absolutePath = ManagerUtils.getAbsolutePath(path);
        List<MetadataDto> metadataListInBo = metadataCoreManager.getMetadataListInBo(metadataProjectService.getProjPath(absolutePath), metadataTypes);
        return metadataListInBo;
    }

    @Override
    public List<GspMetadata> getMetadataByFilter(String path, MetadataFilter metadataFilter) {
        String absolutePath = ManagerUtils.getAbsolutePath(path);
        List<GspMetadata> metadataByFilter = metadataCoreManager.getMetadataByFilter(absolutePath, metadataFilter);
        return metadataByFilter;
    }

    @Override
    public boolean validateRepeatName(String path, String fileName) {
        String absolutePath = ManagerUtils.getAbsolutePath(path);
        return metadataCoreManager.validateRepeatName(absolutePath, fileName);
    }

    @Override
    public List<MetadataType> getMetadataTypeList() {
        return metadataCoreManager.getMetadataTypeList();
    }

    @Override
    public boolean isMetadataExist(String path, String metadataFileName) {
        String absolutePath = Paths.get(ManagerUtils.getAbsolutePath(path)).resolve(metadataFileName).toString();
        return metadataCoreManager.isMetadataExist(absolutePath);
    }

    @Override
    public boolean isMetadataExistInProject(String path, String metadataID) {
        String projPath = metadataProjectService.getProjPath(ManagerUtils.getAbsolutePath(path));
        return metadataCoreManager.isMetadataExistInProject(projPath, metadataID);
    }

    @Override
    public String getRefPath(String path) {
        String absolutePath = ManagerUtils.getAbsolutePath(path);
        return metadataCoreManager.getRefPath(absolutePath);
    }

    @Override
    public MetadataHeader getRefMetadataHeader(String metadataID, String path) {
        String absolutePath = ManagerUtils.getAbsolutePath(path);
        return metadataCoreManager.getRefMetadataHeader(metadataID, absolutePath);
    }

    @Override
    public List<GspMetadata> getMetadataList(String spacePath) {
        String absolutePath = ManagerUtils.getAbsolutePath(spacePath);
        List<GspMetadata> result = metadataCoreManager.getMetadataList(absolutePath);
        return result;
    }

    @Override
    public MetadataPackage getMetadataPackageInfo(String packageFileName, String packagePath) {
        if (packagePath.isEmpty()) {
            packagePath = ManagerUtils.getMetadataPackageLocation();
        }

        return metadataCoreManager.getMetadataPackageInfo(packageFileName, packagePath);
    }

    @Override
    public List<GspMetadata> getMetadataListByRefedMetadataId(String path, String metadataId) {
        String absolutePath = ManagerUtils.getAbsolutePath(path);
        String metadataPath = new FileServiceImp().getCombinePath(metadataProjectService.getProjPath(absolutePath), Utils.getMetadataProjPath());
        return metadataCoreManager.getMetadataListByRefedMetadataId(metadataPath, metadataId);
    }

    @Override
    public Metadata4Ref getMetadataFromPackage(String packageName, String packagePath, String metadataID) {

        if (packagePath.isEmpty()) {
            packagePath = ManagerUtils.getMetadataPackageLocation();
        }
        return metadataCoreManager.getMetadataFromPackage(packageName, packagePath, metadataID);
    }

    @Override
    public MetadataProject getMetadataProjInfo(String path) {
        String absolutePath = ManagerUtils.getAbsolutePath(path);
        return metadataCoreManager.getMetadataProjInfo(absolutePath);
    }

    @Override
    public List<MetadataIndexItemDto> getRemoteMetadataIndexList(String text, String path, String selectedPackageSource,
        List<String> typeList, boolean page, int pageSize, int pageIndex, boolean isFilterByRefs,
        boolean conflictAvoidFlag) {
        String absolutePath = ManagerUtils.getAbsolutePath(path);
        return metadataCoreManager.getRemoteMetadataIndexList(text, absolutePath, selectedPackageSource, typeList, page, pageSize, pageIndex, isFilterByRefs, conflictAvoidFlag);
    }

    @Override
    public List<MetadataIndexItemDto> getLocalMetadataList(String text, String path, List<String> typeList,
        boolean page, int pageSize, int pageIndex) {
        String absolutePath = ManagerUtils.getAbsolutePath(path);
        return metadataCoreManager.getLocalMetadataList(text, absolutePath, typeList, page, pageSize, pageIndex, ManagerUtils.getMetadataPackageLocation());
    }

    @Override
    public Metadata4RefDto pickMetadataIndex(int scopeType, String currentPath,
        MetadataIndexItemDto metadataIndexItemDto, boolean isNeedMdDto) {
        String absolutePath = ManagerUtils.getAbsolutePath(currentPath);
        if (scopeType == 1 || scopeType == 2) {
            absolutePath = metadataProjectService.getProjPath(absolutePath);
        }
        return metadataCoreManager.pickMetadataIndex(scopeType, absolutePath, metadataIndexItemDto, isNeedMdDto, ManagerUtils.getMetadataPackageLocation(), ManagerUtils.getMavenStoragePath());
    }

    @Override
    public GspProject getGspProjectInfo(String path) {
        try {
            return gspProjectService.getGspProjectInfo(path);
        } catch (IOException e) {
            log.error("获取工程信息失败，请检查工程路径");
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public List<MetadataHeader> getResourceMetadata(String metadataId, String path) {
        String absolutePath = ManagerUtils.getAbsolutePath(path);
        MetadataProject projInfo = metadataProjectService.getMetadataProjInfo(absolutePath);
        return metadataCoreManager.getResourceMetadata(metadataId, projInfo.getProjectPath());
    }

    @Override
    public void setMetadataUri(String path) {
        String absolutePath = ManagerUtils.getAbsolutePath(path);
        metadataCoreManager.setMetadataUri(absolutePath);
    }

    @Override
    public GspMetadata getI18nMetadata(String fileName, String path, String language) {
        String absolutePath = ManagerUtils.getAbsolutePath(path);
        return metadataCoreManager.getI18nMetadata(fileName, absolutePath, language);
    }

    @Override
    public List<GspMetadata> GetRefI18nMetadata(String resourceMdID, String resourceFileName, String path) {
        String absolutePath = ManagerUtils.getAbsolutePath(path);
        String packagePath = ManagerUtils.getMetadataPackageLocation();
        String mavenPath = ManagerUtils.getMavenStoragePath();
        return metadataCoreManager.getRefI18nMetadata(resourceMdID, resourceFileName, absolutePath, mavenPath, packagePath);
    }

    @Override
    public void saveMetadata(GspMetadata metadata, String fullPath) {
        String absolutePath = ManagerUtils.getAbsolutePath(fullPath);
        metadataCoreManager.saveMetadata(metadata, absolutePath);
    }

    @Override
    public String getIndexServerStatus(String ip, String port) {
        return metadataCoreManager.getIndexServerStatus(ip, port);
    }

    @Override
    public IMdExtRuleContent getMdExtRule(String metadataId, String path) {
        GspMetadata metadata = loadMetadataByMetadataId(metadataId, path);
        if (!Objects.isNull(metadata)) {
            return metadata.getExtendRule();
        }
        return null;
    }

    @Override
    public void saveMdExtRule(String metadataId, String path, IMdExtRuleContent extendRule) {
        try {
            GspMetadata metadata = loadMetadataByMetadataId(metadataId, path);
            if (Objects.isNull(metadata)) {
                throw new RuntimeException("不存在ID为" + metadataId + ",路径为" + path + "的元数据");
            }
            metadata.setExtendRule(extendRule);
            saveMetadata(metadata, path);
        } catch (Exception e) {
            throw new RuntimeException("保存元数据扩展规则报错", e);
        }
    }

    @Override
    public boolean isMetadataRefed(String path) {
        String absolutePath = ManagerUtils.getAbsolutePath(path);
        return metadataCoreManager.isMetadataRefed(absolutePath);
    }
}
